#ifndef _ALARM_H_
#define _ALARM_H_
#include "TechLib.h"
#pragma pack(1)
#include "Tech.h"
#include <PlatformStruct.h>
#include "Tick.h"
#include <thread>
#include <mutex>

#define ALARM_TYPE_DIFFPERCENTMORE	1
#define ALARM_TYPE_DIFFPERCENTLESS	2
#define ALARM_TYPE_TRADEVOLUME		3
// some fixed length
#define	STKLIB_MAX_CODE			8
#define	STKLIB_MAX_CODE2		16	
#define	STKLIB_MAX_NAME			16
#define	STKLIB_MAX_NAMEENU		80
#define	STKLIB_MAX_SHORTNAME	16
#define	STKLIB_MAX_DOMAIN		32
#define	STKLIB_MAX_PROVINCE		32

typedef struct _alarm_cond_t {
	int	m_type;
	DWORD	m_dwMarket;
	char	m_szCode[STKLIB_MAX_CODE2];
	float	m_fValue;
	char	m_szReserved[32];
}ALARMCOND;

typedef vector<ALARMCOND>	CAlarmCondArray;

class TECH_API  CAlarmCondContainer : public CAlarmCondArray
{
public:
	CAlarmCondContainer(){}
	virtual ~CAlarmCondContainer()	{	RemoveAll();	}

	// for access CAlarmCondArray
	virtual	void	RemoveAll( )
	{
		std::unique_lock<std::mutex>	l(m_mutex);
		CAlarmCondArray::clear();
	}

	virtual	int Add( ALARMCOND & newElement)
	{
		std::unique_lock<std::mutex>	l(m_mutex);
		CAlarmCondArray::push_back(newElement);
		return size()-1;
	}
	virtual	void RemoveAt(int nIndex, int nCount = 1)
	{
		std::unique_lock<std::mutex>	l(m_mutex);
		//CAlarmCondArray::RemoveAt(nIndex,nCount);
		CAlarmCondArray::erase(begin()+nIndex,begin()+nIndex+nCount-1);
	}

	// extra
	static string	AlarmCondToString( ALARMCOND & cond );

protected:
	CAlarmCondContainer(const CAlarmCondContainer&);
	CAlarmCondContainer& operator=(const CAlarmCondContainer&);
	std::mutex	m_mutex;
};

typedef struct _alarm_t {
	Tick		report;
	ALARMCOND	cond;
}ALARM;

typedef std::vector<ALARM>	CAlarmArray;

class TECH_API CAlarmContainer : public CAlarmArray
{
public:
	CAlarmContainer(){}
	static string	GetDescript( ALARM & alarm );

	enum { MaxAlarms = 1024 };

	virtual ~CAlarmContainer()	{	RemoveAll();	}

	// for access CAlarmArray
	virtual	void	RemoveAll( )
	{	CAlarmArray::clear();	}

	virtual	int Add( ALARM & newElement)
	{
		std::unique_lock<std::mutex>	l(m_mutex);
		if( size()>=MaxAlarms ) return -1;
		CAlarmArray::push_back(newElement);
		return size()-1;
	}
	virtual	void RemoveAt(int nIndex, int nCount = 1)
	{
		std::unique_lock<std::mutex>	l(m_mutex);
		//CAlarmArray::RemoveAt(nIndex,nCount);
		CAlarmArray::erase(begin()+nIndex,begin()+nIndex+nCount);
	}

	// process
	bool	HasWarning( )	{	return size() > 0; }
	int		AddAlarm( ALARMCOND * pcond, Tick * pReport, Tick * pReportLast );
	bool	OnReceiveReport( InstrumentInfo * pInfo, Tick * pReport, Tick * pReportLast );

protected:
	CAlarmContainer(const CAlarmContainer&);
	CAlarmContainer& operator=(const CAlarmContainer&);
	mutex	m_mutex;
};

 TECH_API CAlarmContainer &  AfxGetAlarmContainer();

 TECH_API CAlarmCondContainer&  AfxGetAlarmCondContainer();

#pragma pack()

#endif
